home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / fviewsrc.zip / FOSCOM.C < prev    next >
C/C++ Source or Header  |  1993-01-04  |  16KB  |  556 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /* Copyright 1989, Doug Boone   FidoNet 119/5                               */
  4. /* Copyright 1989, John Valentyn FidoNet 114/18                             */
  5. /*                                                                          */
  6. /*                              (916) 893-9019 Data                         */
  7. /*                              (916) 891-0748 voice                        */
  8. /*                              P.O. Box 5108, Chico, CA. 95928             */
  9. /*                                                                          */
  10. /* Originally by John Vallentyn (FidoNet 114/15), so you'll need his        */
  11. /* permission too.                                                          */
  12. /*                                                                          */
  13. /* This program is not for sale. It is for the free use with Opus systems.  */
  14. /* You may not sell it in ANY way. If you have an access charge to your     */
  15. /* Bulletin Board, consider this to be like Opus, you can ONLY make it      */
  16. /* available for download in an open area, where non-members can get access */
  17. /*                                                                          */
  18. /* If you need to modify this source code, please send me a copy of the     */
  19. /* changes you've made so that everyone can share in the updates.           */
  20. /*                                                                          */
  21. /* "Don't rip me off!" -- Tom Jennings, FidoNet's founder                   */
  22. /*                                                                          */
  23. /*--------------------------------------------------------------------------*/
  24.  
  25. #include     <stdio.h>
  26. #include     <ctype.h>
  27. #include     <time.h>
  28. #include    <dos.h>
  29. #include    <conio.h>
  30. #include    <stdarg.h>
  31. #include    <stdlib.h>
  32. #ifdef TURBOC
  33. #include    <alloc.h>
  34. #include <sys\timeb.h>
  35. #else
  36. #include    <malloc.h>
  37. #endif
  38. #include    "archdr.h"
  39.  
  40. extern    int        baud;
  41. extern    int        port;
  42. extern    int        flags;
  43. extern    int        line;
  44. extern    int        screen;
  45. extern    int        ctrl_err;
  46. extern  long    quit_time;
  47.  
  48. extern    int  (cdecl * cdecl sdisplay)(char *);    /* ptr to display function */
  49. extern    int  (cdecl * cdecl get_a_char)(void);    /* instead of getch()    */
  50. extern    int  (cdecl * cdecl chk_keyboard)(void);    /* instead of kbhit()    */
  51.  
  52. int        GetDriverInfo(void);
  53. int        CkFossilCD(void);
  54. int     Com_(unsigned,unsigned);
  55. int     Comm_Set_Baud(int,int,int,int);
  56. void     Comm_transmit(int);
  57. int     Comm_Receive(void);
  58. int     Get_Comm_Status(void);
  59. int     Comm_Char_Avail(void);
  60. int     Comm_Init(int,int,int,int);
  61. void     Comm_De_Init(void);
  62. void     Comm_Dtr(int);
  63. void     Comm_flush_out(void);
  64. void     Comm_Purge_out(void);
  65. void     Comm_Purge_in(void);
  66. void     Comm_Watch(int);
  67. char     Comm_Peek(void);
  68. int     Comm_CD(void);
  69. int     locputs(register char *);
  70. int     fosputs(register char *);
  71. int     play(const char *,...);
  72. void     sendbyte(byte);
  73. void    ask_more(void);
  74.  
  75. extern  void    terminate(int);
  76.  
  77. struct fos_info {    /* info avail via 0x1B function           */
  78.    int    info_size;    /* Offset 0 (word) = Structure size       */
  79.    char    fos_spec;    /*        2 (byte) = FOSSIL spec version  */
  80.    char    drvr_rev;    /*        3 (byte) = Driver rev level     */
  81.    char far *fos_id;    /*        4 (dwrd) = Pointer to ASCII ID  */
  82.    int    ibuf_sz;    /*        8 (word) = Input buffer size    */
  83.    int    ibuf_free;    /*       0A (word) = Bytes avail (input)  */
  84.    int    obuf_sz;    /*       0C (word) = Output buffer size   */
  85.    int    obuf_free;    /*       0E (word) = Bytes avail (output) */
  86.    char    scrn_width;    /*       10 (byte) = Screen width, chars  */
  87.    char    scrn_height;    /*       11 (byte) = Screen height, chars */
  88.    char    baud_msk;    /*       12 (byte) = Baud rate mask       */
  89. } fossil_info =
  90.    { 0, 0, 0, 0L, 0, 0, 0, 0, 0, 0, 0 };
  91.  
  92.  
  93. /* ====================================================================
  94.  * Fill in the fossil information block
  95.  * ====================================================================
  96.  */
  97. int GetDriverInfo(void)
  98. {
  99.     union REGS regs;
  100.     struct SREGS segregs;
  101.     int result;
  102.     char far *p;
  103.  
  104.     p = (char far *) &fossil_info;
  105.     regs.h.al = 0;
  106.     regs.h.ah = 0x1B;            /* function = get driver info */
  107.     regs.x.cx = sizeof(struct fos_info);
  108.     regs.x.di = FP_OFF (p);
  109.     segregs.es = segregs.ds = FP_SEG (p);
  110.     regs.x.dx = port;
  111.     result=int86x(FOSSIL_INT, ®s, ®s, &segregs);
  112.     return(result);
  113. }
  114.  
  115. /* ====================================================================
  116.  *  CkFossilCD() -- Check if Fossil initiallized and CD on
  117.  * ====================================================================
  118.  */
  119. int CkFossilCD(void)
  120. {
  121.     union REGS regs;
  122.     long far *INTword;
  123.     int far *IDword;
  124.  
  125.     INTword = (long far *) 0x50;      /* get interrupt pointer for INT 14h function */
  126.     IDword  = (int far *) *INTword+3; /* point to sig word 1954 and add offset */
  127.     if(*IDword != 0x1954) {           /* if FOSSIL not installed */
  128.         printf("FOSSIL not installed...\n");
  129.         return(FALSE);
  130.         }
  131.     regs.h.al = 0;
  132.     regs.h.ah = 0x04;    /* function = initialize driver */
  133.     regs.x.dx = port;
  134.     regs.x.bx = 0;        /* no ^C */
  135.     int86(FOSSIL_INT, ®s, ®s);
  136.     if(regs.x.ax != 0x1954)
  137.         return(FALSE);        /* unable to initialize fossil */
  138.     if (flags & FOSSIL) {
  139.         Comm_Dtr(1);        /* insure that DTR is on */
  140.         return(Get_Comm_Status() & DCD);    /* return DCD */
  141.         }
  142.     else
  143.         return(TRUE);
  144. }
  145.  
  146. /* ====================================================================
  147.  * General purpose comm function
  148.  * ====================================================================
  149.  */
  150. int Com_(unsigned funct,unsigned chr)
  151. {
  152.     union REGS regs;
  153.     int result;
  154.  
  155.     regs.h.al = (byte)chr;
  156.     regs.h.ah = (byte)funct;
  157.     regs.x.dx = port;
  158.     result=int86(FOSSIL_INT, ®s, ®s);
  159.     return(result);
  160. }
  161.  
  162. /* ====================================================================
  163.  * fossil function 0 = Set baud rate
  164.  * ====================================================================
  165.  */
  166. int Comm_Set_Baud(int BaudRate,
  167.           int DataBits,
  168.           int StopBits,
  169.           int Parity)
  170.     union REGS regs;
  171.     register int value;
  172.  
  173.     switch(BaudRate/300) {
  174.         case 1:   value = 0x40;    break;
  175.         case 2:   value = 0x60;    break;
  176.         case 4:   value = 0x80;    break;
  177.         case 8:   value = 0xA0;    break;
  178.         case 16:  value = 0xC0;    break;
  179.         case 32:  value = 0xE0;    break;
  180.         case 64:  value = 0;    break;
  181.         default: return(FALSE);
  182.         }
  183.     switch (Parity) {
  184.         case 0: break;
  185.         case 1: value |= 0x8; break;
  186.         case 2: value |= 0xA; break;
  187.         default: return(FALSE);
  188.         }
  189.     switch(StopBits-1) {
  190.         case 0: break;
  191.         case 1: value |= 0x4; break;
  192.         default: return(FALSE);
  193.         }
  194.     switch (DataBits-7)    {
  195.         case 0: value |= 0x2; break;
  196.         case 1: value |= 0x3; break;
  197.         default: return(FALSE);
  198.         }
  199.     regs.h.ah = 0x00;
  200.     regs.h.al = (byte)value;
  201.     regs.x.dx = port;
  202.     int86(FOSSIL_INT, ®s, ®s);
  203.     return(TRUE);
  204.  
  205. /* ====================================================================
  206.  * fossil function 1 - transmit character with wait
  207.  * ====================================================================
  208.  */
  209. void Comm_transmit(int chr)
  210. {
  211.     union REGS regs;
  212.  
  213.     regs.h.ah = 0x01;
  214.     regs.h.al = (byte)chr;
  215.     regs.x.dx = port;
  216.     int86(FOSSIL_INT, ®s, ®s);
  217.     return;
  218.  
  219. /* ====================================================================
  220.  * fossil function 2 - receive character with wait
  221.  * ====================================================================
  222.  */
  223. int Comm_Receive(void)
  224. {
  225.     union REGS regs;
  226.  
  227.     do {        /* Watch carrier while waiting for next charatcher */
  228.         if (Comm_CD() == FALSE)
  229.             terminate(3);
  230.         if (kbhit())         /* Allows local keyboard over-ride */
  231.             return(getch());
  232.         } while (Comm_Peek() == 0xff);
  233.   
  234.     regs.h.ah = 0x02; 
  235.     regs.h.al = 0x00;
  236.     regs.x.dx = port;
  237.     int86(FOSSIL_INT, ®s, ®s);
  238.     regs.h.ah = 0x00;
  239.     return(regs.x.ax); 
  240.  
  241. /* ====================================================================
  242.  * get status of comm port
  243.  * ====================================================================
  244.  */
  245. int Get_Comm_Status(void)
  246. {
  247.     union REGS regs;
  248.  
  249.     regs.h.ah = 0x03;    /* function = request status */
  250.     regs.h.al = 0x00; 
  251.     regs.x.dx = port;
  252.     int86(FOSSIL_INT, ®s, ®s);
  253.  
  254.     if (!(regs.x.ax & DCD) && flags & FOSSIL)
  255.         terminate(3);
  256.  
  257.     if (regs.x.ax == 0xffff)        /* Hangs sometimes clear buffer */
  258.         Comm_Purge_out();
  259.  
  260.     return(regs.x.ax);
  261.  
  262. /* ====================================================================
  263.  * check if character available in input buffer
  264.  * ====================================================================
  265.  */
  266. int Comm_Char_Avail(void)
  267. {
  268.     union REGS regs;
  269.  
  270.     regs.h.ah = 0x03;    /* function = request status */
  271.     regs.h.al = 0x00;
  272.     regs.x.dx = port;
  273.     int86(FOSSIL_INT, ®s, ®s); 
  274.     regs.x.ax = regs.x.ax & 0x0100;    /* check input data avail, ah bit 0 */
  275.     if (regs.x.ax == 0)
  276.         return(FALSE);
  277.     return(TRUE);
  278. }
  279.  
  280. /* ====================================================================
  281.  * function 4 - initialize driver
  282.  * ==================================================================== */
  283. int Comm_Init(int BaudRate,
  284.       int DataBits,
  285.       int StopBits,
  286.       int Parity)
  287. {
  288.     union REGS regs;
  289.  
  290.     regs.h.ah = 0x04;
  291.     regs.h.al = (byte)(BaudRate | DataBits | StopBits | Parity);
  292.     regs.x.dx = port;
  293.     regs.x.bx = 0;    /* no ^C code */ 
  294.     int86(FOSSIL_INT, ®s, ®s);
  295.     return(regs.x.ax);
  296. }
  297.  
  298. /* ====================================================================
  299.  * function 5 - deinitialize driver
  300.  * ====================================================================
  301.  */
  302. void Comm_De_Init(void)
  303. {
  304.     union REGS regs;
  305.  
  306.     regs.h.ah = 0x05;
  307.     regs.h.al = 0;
  308.     regs.x.dx = port;
  309.     int86(FOSSIL_INT, ®s, ®s);
  310.     return;
  311.  
  312. /* ====================================================================
  313.  * function 6 - Raise/Lower DTR
  314.  * ====================================================================
  315.  */
  316. void Comm_Dtr(int flag)
  317. {
  318.     union REGS regs;
  319.  
  320.     regs.h.ah = 0x06;
  321.     regs.h.al = (byte)flag;    /* 01h=Raise 00h=Lower */
  322.     regs.x.dx = port;
  323.     int86(FOSSIL_INT, ®s, ®s);
  324.     return;
  325. }
  326.  
  327. /* ====================================================================
  328.  * function 8 - flush output buffer
  329.  * ====================================================================
  330.  */
  331. void Comm_flush_out(void)
  332. {
  333.     union REGS regs;
  334.  
  335.     regs.h.ah = 0x08;
  336.     regs.h.al = 0x00;
  337.     regs.x.dx = port; 
  338.     int86(FOSSIL_INT, ®s, ®s);
  339.     return;
  340.  
  341. /* ====================================================================
  342.  * function 9 - purge output buffer
  343.  * ====================================================================
  344.  */
  345. void Comm_Purge_out(void)
  346. {
  347.     union REGS regs;
  348.  
  349.     regs.h.ah = 0x09;
  350.     regs.h.al = 0x00;
  351.     regs.x.dx = port;
  352.     int86(FOSSIL_INT, ®s, ®s);
  353.     return;
  354. }
  355.  
  356. /* ====================================================================
  357.  * function 10 (0Ah) - purge input buffer
  358.  * ====================================================================
  359.  */
  360. void Comm_Purge_in(void)
  361. {
  362.     union REGS regs;
  363.  
  364.     regs.h.ah = 0x0A;
  365.     regs.h.al = 0x00;
  366.     regs.x.dx = port;
  367.     int86(FOSSIL_INT, ®s, ®s);
  368.     return;
  369. }
  370.  
  371. /* ====================================================================
  372.  * function 14 - Watchdog On/Off
  373.  * ====================================================================
  374.  */
  375. void Comm_Watch(int flag)
  376. {
  377.     union REGS regs;
  378.  
  379.     regs.h.ah = 0x14;
  380.     regs.h.al = (byte)flag;    /* 01h=Watchdog on 00h=Watchdog off */
  381.     regs.x.dx = port;
  382.     int86(FOSSIL_INT, ®s, ®s);
  383.     return;
  384. }
  385. /*--------------------------------------------------------------------------*/
  386. /* Look ahead at input buffer, primarily to check for ^C                    */
  387. /*--------------------------------------------------------------------------*/
  388. char Comm_Peek(void)
  389. {
  390.     union REGS regs;
  391.  
  392.     regs.h.ah = 0x0C;
  393.     regs.x.dx = port;
  394.     int86(FOSSIL_INT, ®s,®s);
  395.     return(regs.h.al);
  396. }
  397.  
  398. /* ====================================================================
  399.  *  Check for carrier detect returns TRUE (1) while carrier is high
  400.  * ====================================================================
  401.  */
  402. int Comm_CD(void)
  403. {
  404.     union REGS regs;
  405.  
  406.     regs.h.ah = 0x03;
  407.     regs.x.dx = port;
  408.     int86(FOSSIL_INT, ®s,®s);
  409.     if (regs.h.al & DCD)
  410.         return(TRUE);
  411.     else
  412.         return(FALSE);
  413. }
  414.  
  415.  
  416. /* ====================================================================
  417.  *  Local display function - access via display()
  418.  * ====================================================================
  419.  */
  420. int locputs(register char *str)
  421. {
  422.     register int c;
  423.  
  424.     while (*str && ctrl_err) {
  425.         c = *str++;
  426.         putchar(c);
  427.         if (c == '\n')
  428.             line++;
  429.         if (line > (screen-2) && flags & MORE)
  430.             ask_more();
  431.         }
  432.     return(0);
  433. }
  434.  
  435. /* ====================================================================
  436.  *  Fossil display function - access via display()
  437.  * ====================================================================
  438.  */
  439. int fosputs(register char *str)
  440. {
  441.     register int c;
  442.  
  443.     while (*str && ctrl_err) {
  444.         c = *str++;
  445.         putchar(c);        /* So what's going on will display locally!! */
  446.         if(c == '\n') {
  447.             Comm_transmit('\r');
  448.             line++;
  449.             if (Comm_Peek() == 0x13) {
  450.                 Comm_Purge_in();
  451.                 while (Comm_Peek() == 0xff);
  452.                 Comm_Purge_in();
  453.                 }
  454.             else if (Comm_Peek() == 0x03) {
  455.                 Comm_Purge_in();
  456.                 Comm_Purge_out();
  457.                 ctrl_err = 0;
  458.                 }
  459.             }
  460.         Comm_transmit(c);
  461.         if (line > (screen-2) && flags & MORE)
  462.             ask_more();
  463.         }
  464.     while(!(Get_Comm_Status() & TSRE));    /* wait for output buffer to empty */
  465.     return(0);
  466. }
  467.  
  468. /* ====================================================================
  469.  * display is a printf function to either the console or the comm port
  470.  * note that the argument is variable (therefore must be cdecl convention)
  471.  * ====================================================================
  472.  */
  473. int play(const char *fmt,...)
  474. {
  475.     char pbuf[BUFSIZ];
  476.     va_list arg_ptr;
  477.  
  478.     va_start(arg_ptr, fmt);
  479.     vsprintf(pbuf, fmt, arg_ptr);
  480.     va_end(arg_ptr);
  481.     sdisplay(pbuf);
  482.     return(0);
  483. }
  484.  
  485. /* ====================================================================
  486.  * sendbyte outputs a character to either the console or the comm port
  487.  * ====================================================================
  488.  */
  489. void sendbyte(byte ch)
  490. {
  491.  
  492.     if(flags & FOSSIL) {
  493.         if(ch == '\n') {
  494.             Comm_transmit('\r');
  495.             line++;
  496.             if (!(Comm_CD()))
  497.                 terminate(3);
  498.             }
  499.         Comm_transmit(ch);
  500.         putchar(ch);
  501.         while(!(Get_Comm_Status() & TSRE));    /* wait for output buffer to empty */
  502.         return;
  503.         }
  504.     else
  505.         putchar(ch);
  506.     return;
  507. }
  508. /*--------------------------------------------------------------------------*/
  509. /* If user has More? on in their user record                                */
  510. /*--------------------------------------------------------------------------*/
  511.  
  512. void    ask_more(void)
  513. {
  514.     char    ch;
  515.  
  516.     line = 0;
  517.  
  518.     if (quit_time < time(NULL))        /* Check the time */
  519.         ctrl_err = 0;
  520.  
  521.     if (flags & FOSSIL) {        /* Check carrier, exit(3) if lost */
  522.         if (!(Comm_CD()))
  523.             terminate(3);
  524.  
  525.     if (Comm_Peek() == 0x03) {        /* Check for ^C inbound buffer */
  526.             ctrl_err = 0;
  527.             Comm_Purge_in();        /* Clear all buffers */
  528.             Comm_Purge_out();
  529.             }
  530.         }
  531.     sdisplay("More [Y,n,=]?  ");
  532.     ch = get_a_char();
  533.     sdisplay("\n");
  534.     switch(ch) {
  535.  
  536.         case '\03':
  537.         case 'n':
  538.         case 'N':     ctrl_err = 0;
  539.                     return;
  540.  
  541.         case '=':
  542.         case '+':     flags &= ~MORE;
  543.                     break;
  544.  
  545.         default:    break;
  546.         }
  547.     return;
  548. }
  549.